package application

import (
	"context"
	"fmt"
	"io"
	"os"
	"runtime"

	"github.com/gin-gonic/gin"

	"gitee.com/go-kade/library/ioc"
	"gitee.com/go-kade/library/ioc/config/log"
)

type Http struct {
	// 默认根据
	Enable *bool `json:"enable" yaml:"enable" toml:"enable" env:"HTTP_ENABLE"`
	// HTTP服务Host
	Host string `json:"size" yaml:"size" toml:"size" env:"HTTP_HOST"`
	// HTTP服务端口
	Port int `json:"port" yaml:"port" toml:"port" env:"HTTP_PORT"`

	// 使用的http框架, 启用后会自动从ioc中加载 该框架的hanlder
	WEB_FRAMEWORK WEB_FRAMEWORK `json:"web_framework" yaml:"web_framework" toml:"web_framework" env:"HTTP_WEB_FRAMEWORK"`

	// HTTP服务器参数
	ReadHeaderTimeoutSecond int `json:"read_header_timeout" yaml:"read_header_timeout" toml:"read_header_timeout" env:"HTTP_READ_HEADER_TIMEOUT"`
	// 读取HTTP整个请求时的参数
	ReadTimeoutSecond int `json:"read_timeout" yaml:"read_timeout" toml:"read_timeout" env:"HTTP_READ_TIMEOUT"`
	// 响应超时事件
	WriteTimeoutSecond int `json:"write_timeout" yaml:"write_timeout" toml:"write_timeout" env:"HTTP_WRITE_TIMEOUT"`
	// 启用了KeepAlive时 复用TCP链接的超时时间
	IdleTimeoutSecond int `json:"idle_timeout" yaml:"idle_timeout" toml:"idle_timeout" env:"HTTP_IDLE_TIMEOUT"`
	// header最大大小
	MaxHeaderSize string `json:"max_header_size" yaml:"max_header_size" toml:"max_header_size" env:"HTTP_MAX_HEADER_SIZE"`

	// SSL启用参数
	EnableSSL bool   `json:"enable_ssl" yaml:"enable_ssl" toml:"enable_ssl" env:"HTTP_ENABLE_SSL"`
	CertFile  string `json:"cert_file" yaml:"cert_file" toml:"cert_file" env:"HTTP_CERT_FILE"`
	KeyFile   string `json:"key_file" yaml:"key_file" toml:"key_file" env:"HTTP_KEY_FILE"`

	// 开启Trace
	EnableTrace bool `toml:"enable_trace" json:"enable_trace" yaml:"enable_trace"  env:"HTTP_ENABLE_TRACE"`
	// 开启HTTP健康检查
	EnableHealthCheck bool `toml:"enable_health_check" json:"enable_health_check" yaml:"enable_health_check"  env:"HTTP_ENABLE_HEALTH_CHECK"`
	// 开启跨越允许
	EnableCors bool `toml:"enable_cors" json:"enable_cors" yaml:"enable_cors"  env:"HTTP_ENABLE_CORS"`

	// 是否开启API Doc
	EnableApiDoc bool `json:"enable_api_doc" yaml:"enable_api_doc" toml:"enable_api_doc" env:"HTTP_ENABLE_API_DOC"`
	// Swagger API Doc URL路径
	ApiDocPath string `json:"api_doc_path" yaml:"api_doc_path" toml:"api_doc_path" env:"HTTP_API_DOC_PATH"`

	// 解析后的数据
	// maxHeaderBytes uint64
	// log               *zerolog.Logger
	// server            *http.Server
	// routerBuilders    map[WEB_FRAMEWORK]RouterBuilder `json:"-" yaml:"-" toml:"-" env:"-"`
	RouterBuildConfig *BuildConfig
}

type RouterBuilder interface {
	// Config(*BuildConfig)
	// Build() (http.Handler, error)
}

type BuildConfig struct {
	// 装载Ioc路由之前
	// BeforeLoad BuildHook `json:"-" yaml:"-" toml:"-" env:"-"`
	// // 装载Ioc路由之后
	// AfterLoad BuildHook `json:"-" yaml:"-" toml:"-" env:"-"`
}

type WEB_FRAMEWORK string

const (
	WEB_FRAMEWORK_GO_RESTFUL WEB_FRAMEWORK = "go-restful"
	WEB_FRAMEWORK_GIN        WEB_FRAMEWORK = "gin"
)

func NewDefaultHttp() *Http {
	return &Http{
		Host:                    "localhost",
		Port:                    8080,
		ReadHeaderTimeoutSecond: 30,
		ReadTimeoutSecond:       60,
		WriteTimeoutSecond:      60,
		IdleTimeoutSecond:       300,
		MaxHeaderSize:           "16kb",
		EnableTrace:             true,
		WEB_FRAMEWORK:           WEB_FRAMEWORK_GIN,
		// routerBuilders: map[WEB_FRAMEWORK]RouterBuilder{
		// 	WEB_FRAMEWORK_GO_RESTFUL: NewGoRestfulRouterBuilder(),
		// 	WEB_FRAMEWORK_GIN:        NewGinRouterBuilder(),
		// },
		// RouterBuildConfig: &BuildConfig{},
	}
}

// Start 启动服务
func (h *Http) Start(ctx context.Context) {

	log := ioc.Config().Get(log.AppName).(*log.Config)
	log.File.Enable = true
	log.File.FilePath = "logs/info.log"

	r := gin.Default()
	//os.O_WRONLY 表示以只写模式打开文件，只允许对文件进行写操作，不能进行读取操作。
	file, _ := os.OpenFile(log.File.FilePath, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)

	//这意味着 Gin 框架的日志将会同时被写入到您的日志文件中以及标准输出流中，这样您就可以在控制台上看到日志输出
	gin.DefaultWriter = io.MultiWriter(file, os.Stdout)

	// 使用 Gin 框架提供的默认日志中间件记录日志
	// r.Use(gin.Logger())这是 Gin 框架提供的默认日志中间件，会自动记录请求的详细信息，包括请求方法、请求路径、HTTP 状态码等，并将这些信息记录到 gin.DefaultWriter
	r.Use(gin.Logger())

	r.LoadHTMLGlob("views/*") //配置模版中间件
	ioc.LoadGinApi("/api/v1", r)

	// 设置使用所有 CPU 核心
	runtime.GOMAXPROCS(runtime.NumCPU())
	// 启动 Gin 服务器
	r.Run(fmt.Sprintf(":%d", h.Port))
}
